//----------------------------------------------------------------------------
//  ,-.
// /_\___ ,   Ninja Framework
// '  ___\    (C) Riccardo Capra - http://riccar.do
//  //   \\
//----------------------------------------------------------------------------
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//----------------------------------------------------------------------------

#ifndef NJ_ATOMIC_INLINE_H
#	define NJ_ATOMIC_INLINE_H

	//----------------------------------------------------------------------------
	template <class tType>
	inline NjAtomic<tType>::NjAtomic()
	{
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline NjAtomic<tType>::NjAtomic(NjAtomic const & kCopy)
	:
		Parent(kCopy)
	{
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline NjAtomic<tType>::NjAtomic(Type iCopy)
	:
		Parent(static_cast<typename Parent::Number>(iCopy))
	{
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline NjAtomic<tType>::~NjAtomic()
	{
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline void NjAtomic<tType>::Increment()
	{
		Parent::Increment();
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType>::Type NjAtomic<tType>::PreIncrement()
	{
		return static_cast<Type>(Parent::PreIncrement());
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType>::Type NjAtomic<tType>::PostIncrement()
	{
		return static_cast<Type>(Parent::PostIncrement());
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline void NjAtomic<tType>::Decrement()
	{
		Parent::Decrement();
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType>::Type NjAtomic<tType>::PreDecrement()
	{
		return static_cast<Type>(Parent::PreDecrement());
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType>::Type NjAtomic<tType>::PostDecrement()
	{
		return static_cast<Type>(Parent::PostDecrement());
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline void NjAtomic<tType>::Add(Type iRightValue)
	{
		Parent::Add(static_cast<typename Parent::Number>(iRightValue));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType>::Type NjAtomic<tType>::PreAdd(Type iRightValue)
	{
		return static_cast<Type>(Parent::PreAdd(static_cast<typename Parent::Number>(iRightValue)));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType>::Type NjAtomic<tType>::PostAdd(Type iRightValue)
	{
		return static_cast<Type>(Parent::PostAdd(static_cast<typename Parent::Number>(iRightValue)));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline void NjAtomic<tType>::Sub(Type iRightValue)
	{
		Parent::Sub(static_cast<typename Parent::Number>(iRightValue));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType>::Type NjAtomic<tType>::PreSub(Type iRightValue)
	{
		return static_cast<Type>(Parent::PreSub(static_cast<typename Parent::Number>(iRightValue)));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType>::Type NjAtomic<tType>::PostSub(Type iRightValue)
	{
		return static_cast<Type>(Parent::PostSub(static_cast<typename Parent::Number>(iRightValue)));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType>::Type NjAtomic<tType>::PostOr(Type iRightValue)
	{
		return static_cast<Type>(Parent::PostOr(static_cast<typename Parent::Number>(iRightValue)));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType>::Type NjAtomic<tType>::PostAnd(Type iRightValue)
	{
		return static_cast<Type>(Parent::PostAnd(static_cast<typename Parent::Number>(iRightValue)));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType>::Type NjAtomic<tType>::PostXor(Type iRightValue)
	{
		return static_cast<Type>(Parent::PostXor(static_cast<typename Parent::Number>(iRightValue)));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType>::Type NjAtomic<tType>::PostExchange(Type iValue)
	{
		return static_cast<Type>(Parent::PostExchange(static_cast<typename Parent::Number>(iValue)));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType>::Type NjAtomic<tType>::PostCompareExchange(Type iComparand, Type iValue)
	{
		return static_cast<Type>(Parent::PostCompareExchange(static_cast<typename Parent::Number>(iComparand), static_cast<typename Parent::Number>(iValue)));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline NjBool NjAtomic<tType>::PostSetBit(Type iBit)
	{
		return Parent::PostSetBit(static_cast<typename Parent::Number>(iBit));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline NjBool NjAtomic<tType>::PostResetBit(Type iBit)
	{
		return Parent::PostResetBit(static_cast<typename Parent::Number>(iBit));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType>::Type NjAtomic<tType>::Get() const
	{
		return static_cast<Type>(Parent::Get());
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline void NjAtomic<tType>::Set(Type iValue)
	{
		Parent::Set(static_cast<typename Parent::Number>(iValue));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline NjAtomic<tType *>::NjAtomic()
	{
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline NjAtomic<tType *>::NjAtomic(NjAtomic const & kCopy)
	:
		Parent(kCopy)
	{
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline NjAtomic<tType *>::NjAtomic(Type iCopy)
	:
		Parent(reinterpret_cast<typename Parent::Number>(iCopy))
	{
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline NjAtomic<tType *>::~NjAtomic()
	{
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline void NjAtomic<tType *>::Increment()
	{
		Add(1);
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType *>::Type NjAtomic<tType *>::PreIncrement()
	{
		return PreAdd(1);
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType *>::Type NjAtomic<tType *>::PostIncrement()
	{
		return PostAdd(1);
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline void NjAtomic<tType *>::Decrement()
	{
		Sub(1);
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType *>::Type NjAtomic<tType *>::PreDecrement()
	{
		return PreSub(1);
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType *>::Type NjAtomic<tType *>::PostDecrement()
	{
		return PostSub(1);
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline void NjAtomic<tType *>::Add(NjUint iRightValue)
	{
		Parent::Add(static_cast<typename Parent::Number>(iRightValue)*sizeof(tType));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType *>::Type NjAtomic<tType *>::PreAdd(NjUint iRightValue)
	{
		return reinterpret_cast<Type>(Parent::PreAdd(static_cast<typename Parent::Number>(iRightValue)*sizeof(tType)));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType *>::Type NjAtomic<tType *>::PostAdd(NjUint iRightValue)
	{
		return reinterpret_cast<Type>(Parent::PostAdd(static_cast<typename Parent::Number>(iRightValue)*sizeof(tType)));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline void NjAtomic<tType *>::Sub(NjUint iRightValue)
	{
		Parent::Sub(static_cast<typename Parent::Number>(iRightValue)*sizeof(tType));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType *>::Type NjAtomic<tType *>::PreSub(NjUint iRightValue)
	{
		return reinterpret_cast<Type>(Parent::PreSub(static_cast<typename Parent::Number>(iRightValue)*sizeof(tType)));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType *>::Type NjAtomic<tType *>::PostSub(NjUint iRightValue)
	{
		return reinterpret_cast<Type>(Parent::PostSub(static_cast<typename Parent::Number>(iRightValue)*sizeof(tType)));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType *>::Type NjAtomic<tType *>::PostExchange(Type iValue)
	{
		return reinterpret_cast<Type>(Parent::PostExchange(reinterpret_cast<typename Parent::Number>(iValue)));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType *>::Type NjAtomic<tType *>::PostCompareExchange(Type iComparand, Type iValue)
	{
		return reinterpret_cast<Type>(Parent::PostCompareExchange(reinterpret_cast<typename Parent::Number>(iComparand), reinterpret_cast<typename Parent::Number>(iValue)));
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline typename NjAtomic<tType *>::Type NjAtomic<tType *>::Get() const
	{
		return reinterpret_cast<Type>(Parent::Get());
	}
	//----------------------------------------------------------------------------
	template <class tType>
	inline void NjAtomic<tType *>::Set(Type iValue)
	{
		Parent::Set(reinterpret_cast<typename Parent::Number>(iValue));
	}
	//----------------------------------------------------------------------------

#endif // NJ_ATOMIC_INLINE_H
